---------------------------------------------------------------
-- @Description：         read/write Memdb
---------------------------------------------------------------
local skynet = require "skynet"
require "skynet.manager"
local log = require "sky_log"
local lua_memcached = require "lua_memcached" 
local serpent = require "serpent"

local M = {
    memcache_connect_t = {},
}

--============================= MSG =============================--
function M:connect_memcache(config)
    self.memcache_connect_t[tonumber(config.plat_id)] = {}
    local connect_t = self.memcache_connect_t[tonumber(config.plat_id)]

    local c, ret
    --exp
    if config.memcache_exp then
        local ip = string.match(config.memcache_exp, "(%S+):")
        local port = tonumber(string.match(config.memcache_exp, ":(%d+)"))
        c = lua_memcached.create_libmemcahed_client()
        ret = c:init_libmemcahed_client(ip, port)
        if ret then 
            connect_t.memcache_exp = c
        end
    end
    --signup
    if config.memcache_signup then
        local ip = string.match(config.memcache_signup, "(%S+):")
        local port = tonumber(string.match(config.memcache_signup, ":(%d+)"))
        c = lua_memcached.create_libmemcahed_client()
        ret = c:init_libmemcahed_client(ip, port)
        if ret then 
            connect_t.memcache_signup = c
        end
    end
    --tid
    if config.memcache_tid then
        local ip = string.match(config.memcache_tid, "(%S+):")
        local port = tonumber(string.match(config.memcache_tid, ":(%d+)"))
        c = lua_memcached.create_libmemcahed_client()
        ret = c:init_libmemcahed_client(ip, port)
        if ret then 
            connect_t.memcache_tid = c
        end
    end
    --uid
    if config.memcache_uid then
        local ip = string.match(config.memcache_uid, "(%S+):")
        local port = tonumber(string.match(config.memcache_uid, ":(%d+)"))
        c = lua_memcached.create_libmemcahed_client()
        ret = c:init_libmemcahed_client(ip, port)
        if ret then 
            connect_t.memcache_uid = c
        end
    end
    
    log.warning("connect plat_id ["..config.plat_id.."] memcache success=", self.memcache_connect_t[tonumber(config.plat_id)])
end

function M:get_exp(memcache_type, platid, user_id)
    if not memcache_type
    or not platid
    or not tostring(user_id) 
    or not self.memcache_connect_t[platid]
    or not self.memcache_connect_t[platid][memcache_type] then
        log.error("get_record error! memcache_type=", (memcache_type or "nil")
            .."  platid="..(platid or "nil").."  user_id="..(user_id or "nil")
        ) 
        return 
    end
    
    local c = self.memcache_connect_t[platid][memcache_type]
    log.info("c=", c)

    local ret = c:get_record(tostring(user_id))
    log.info("ret=", ret)
    if not ret then 
        log.error("get_record error! user_id=", (user_id or "nil")) 
    end

    local exp
    if ret and (type(ret)=='string') then 
        exp = string.match(ret, "exp:(%d+)")
    end
    
    return exp
end

function M:set_record(memcache_type, platid, user_id, set_data)
    if not memcache_type
    or not platid
    or not set_data
    or not tostring(user_id) 
    or not self.memcache_connect_t[platid]
    or not self.memcache_connect_t[platid][memcache_type] then
        log.error("set_record error! memcache_type=", (memcache_type or "nil")
            .."  platid="..(platid or "nil").."  user_id="..(user_id or "nil")
            .."  set_data="..(serpent.block(set_data) or "nil") ) 
        return 
    end
    
    local c = self.memcache_connect_t[platid][memcache_type]

    local ret = c:set_record(tostring(user_id), set_data, #set_data)
    if not ret then 
        log.error("set_record error! user_id=", (user_id or "nil")..
            "  set_data="..(set_data or "nil")) 
    end
end

function M:get_tid(memcache_type, platid, user_id)
    if not memcache_type
    or not platid
    or not tostring(user_id) 
    or not self.memcache_connect_t[platid]
    or not self.memcache_connect_t[platid][memcache_type] then
        log.error("get_tid error! memcache_type=", (memcache_type or "nil")
            .."  platid="..(platid or "nil").."  user_id="..(user_id or "nil") ) 
        return 
    end

    local c = self.memcache_connect_t[platid][memcache_type]
    local total_record = c:get_record(tostring(user_id))

    local tid
    if total_record and (type(total_record)=='string') then 
        tid = string.match(total_record, "tid:(%d+)")
    end
    
    return tid
end

function M:get_role(memcache_type, platid, user_id)
    if not memcache_type
    or not platid
    or not tostring(user_id) 
    or not self.memcache_connect_t[platid]
    or not self.memcache_connect_t[platid][memcache_type] then
        log.error("get_tid error! memcache_type=", (memcache_type or "nil")
            .."  platid="..(platid or "nil").."  user_id="..(user_id or "nil") ) 
        return 
    end

    local c = self.memcache_connect_t[platid][memcache_type]
    local total_record = c:get_record(tostring(user_id))

    log.info("total_record=", total_record)
    local role
    if total_record and (type(total_record)=='string') then 
        role = string.match(total_record, "role:(%a+)")
    end
    
    return role
end

function  M:init_by_config(config)
    --log.info("memcache init_by_config=", config)
    if not tonumber(config.plat_id) then
        log.error("memecache connect error: no plat_id!")
        return
    end

    self:connect_memcache(config)
end

--============================= Init =============================--
skynet.start(function ()
    skynet.dispatch("lua", function(session, address, cmd, ...)
        local f = M[cmd]
        if f then
            skynet.ret(skynet.pack(f(M, ...)))
        else
            error(string.format("Unknown command %s", tostring(cmd)))
        end
    end)

    skynet.register(".memcache")
end)

return M